﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using QuickGraph;
using SpriteLib;
using System.Xml.Serialization;

namespace SharedCongkak
{
    [XmlRootAttribute(ElementName = "Path", IsNullable = false)]
    public class Path:QuickGraph.IEdge<AbstractHole>
    {
        private AbstractHole source, target;
        private List<Sprite> pathSprites = new List<Sprite>();
        static Texture2D pathTexture;
        const float radius = 7.5f;
        const int minSpacing = 20;
        float spacing;


        public Path()
        {
        }

        public Path(AbstractHole source, AbstractHole target)
        {
            Source = source;
            Target = target;
        }

        public static void LoadContent(ContentManager content)
        {
            pathTexture = content.Load<Texture2D>("Texture/Path");
        }

        public void Update(GameTime gameTime)
        {

            foreach (var sprite in pathSprites)
            {
                sprite.Update(gameTime);
            }
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            foreach (var sprite in pathSprites)
            {
                sprite.Draw(spriteBatch);
            }

        }

        public void CreatePath()
        {
            Vector2 distance = (Target.Center - Source.Center);
            Vector2 direction = new Vector2(distance.X, distance.Y);
            direction.Normalize();
            float pathLength = distance.Length() - Source.Radius - Target.Radius;
            int noOfSprite = (int)(pathLength / minSpacing)-1;
            spacing = pathLength/(noOfSprite+1);
            Vector2 startPosition =
                Source.Center +
                new Vector2((float)(direction.X * (Source .Radius)), (float)(direction.Y * (Source.Radius)));

            Sprite newSprite = new Sprite();
            for (int i = 0; i < noOfSprite; i++)
            {
                Vector2 position = startPosition + (i + 1) * direction * (spacing);
                newSprite = CreatePathSprite(position);
            }
           
        }

        private void OnEffectEnd(object sender, SpriteEffectArg arg)
        {
            if (sender != pathSprites[pathSprites.Count - 1])
                return;
            else
            {
                foreach (var sprite in pathSprites)
                    sprite.Color = Color.White;
                foreach (var path in Target.NextEdges)
                {
                    path.StartEffect();

                }

            }
        }

        public void StartEffect()
        {
            for (int i = 0; i < pathSprites.Count; i++)
            {
                pathSprites[i].RemoveAllSpriteEffects();
                pathSprites[i].Color = Color.White;
                pathSprites[i].AttachSpriteEffect(new SpriteColorEffect(
                   Color.White,
                   Color.Turquoise,
                   new TimeSpan(0, 0, 0, 0, 0 + i * 500),
                   new TimeSpan(0, 0, 0, 0, 500),
                   1));
            }
        }

        private Sprite CreatePathSprite(Vector2 position)
        {
            Sprite newSprite = new Sprite();
            newSprite.Texture = pathTexture;
            newSprite.Width = pathTexture.Width;
            newSprite.Height = pathTexture.Height;
            newSprite.Center = position;
            newSprite.Color = Color.White;
            newSprite.OnEnd += OnEffectEnd;

            pathSprites.Add(newSprite);
            return newSprite;
        }

        private void HolePositionChange(Object hole, EventArgs args)
        {
            pathSprites.Clear();
            CreatePath();
        }

        #region IEdge<AbstractHole> Members

        [ContentSerializer(SharedResource = true)]
        public AbstractHole Source
        {
            set
            {
                source = value;
                source.OnPositionChanged += HolePositionChange;
            }
            get { return source; }
        }
        [ContentSerializer(SharedResource = true)]
        public AbstractHole Target
        {
            set
            {
                target = value;
                target.OnPositionChanged += HolePositionChange;
            }
            get { return target; }
        }

        #endregion
    }

    public class PathReader : ContentTypeReader<Path>
    {

        protected override Path Read(
                ContentReader input,
                Path existingInstance)
        {

            Path path = new Path();
            input.ReadSharedResource<AbstractHole>(
                (AbstractHole value) => { path.Source = value; }
            );

            input.ReadSharedResource<AbstractHole>(
                (AbstractHole value) => { path.Target = value; }
            );

            return path;
        }


    }
}
